from typing import List
from typing_extensions import Self

from PIL import Image
from PIL import ImageFont

class AppError(Exception):
    def __init__(self, id:str,*args: object) -> None:
        self.id=id
        super().__init__(*args)

class DrawableText:
    def __init__(self,text:str,size:int,font:ImageFont.FreeTypeFont) -> None:
        self.text = text
        self.size = size
        self.font = font
    def __repr__(self) -> str:
        return "<DrawableText '{}' size={}>".format(self.text, str(self.size))

class Font:
    def __init__(self,file:str) -> None:
        self.file = file
        self.cache = {}
        
    def loadFont(self,size:int):
        f = self.cache.get(size, None)
        if not f:
            self.cache[size] = f = ImageFont.truetype(self.file,size)
        return f

class Card:
    def __init__(self, beast:Image.Image,
                    name:DrawableText,damage:DrawableText,
                    show_damage:bool,health:Image.Image,
                    show_health:bool,cost:Image.Image,
                    front:Image.Image, back:Image.Image,
                    abilities:List[Image.Image],decal:Image.Image) -> None:
        self.beast = beast
        self.name = name
        self.damage = damage
        self.show_damage = show_damage
        self.health = health
        self.show_health = show_health
        self.cost = cost
        self.abilities = abilities
        self.front = front
        self.back = back
        self.decal = decal

class StaticCard:
    def __init__(self, beast:str,
                    name:str="",damage:int=0,
                    show_damage:bool="wat",health:int=1,
                    show_health:bool="wat",cost:int=0,
                    cost_type:str="blood",front:str="normal",
                    back:str="normal",abilities:List[str]=[],
                    smoke:bool=False,id:str="") -> None:
        self.beast = beast
        self.name = name
        self.damage = damage
        self.show_damage = show_damage if show_damage != "wat" else self.damage != -1
        self.health = health
        self.show_health = show_health if show_health != "wat" else self.health != -1
        self.cost = cost
        self.cost_type = cost_type
        self.abilities = abilities
        self.front = front or "normal"
        self.back = back or "normal"
        self.smoke = smoke
        self.id = id